<!DOCTYPE html>
<!--[if IEMobile 7 ]><html class="no-js iem7"><![endif]-->
<!--[if lt IE 9]><html class="no-js lte-ie8"><![endif]-->
<!--[if (gt IE 8)|(gt IEMobile 7)|!(IEMobile)|!(IE)]><!--><html class="no-js" lang="en"><!--<![endif]-->
<head>
  <meta charset="utf-8">
  <title>gdb的基本使用方法 &mdash; cat writebug.cn/history</title>
  <meta name="author" content="zhiliao">
  <meta name="description" content="gdb的基本使用方法" />

  <meta name="keywords" content="开发者,程序,博客园,程序猿,程序媛,极客,码农,编程,代码,软件开发,开源,IT网站,技术社区,Developer,Programmer,Coder,Geek,Coding,Code,writebug,bug,写bug,linux,vim,编程语言,调试" />

  <link href="/feeds/all.atom.xml" type="application/rss+xml" rel="alternate"
        title="cat writebug.cn/history RSS Feed" />





  <!-- http://t.co/dKP3o1e -->
  <meta name="HandheldFriendly" content="True">
  <meta name="MobileOptimized" content="320">
  <meta name="viewport" content="width=device-width, initial-scale=1">


    <link href="/favicon.png" rel="icon">

  <link href="/theme/css/main.css" media="screen, projection"
        rel="stylesheet" type="text/css">
  <link href="/theme/css/pygment.css" rel="stylesheet" type="text/css">

  <!--
  <link href="//fonts.googleapis.com/css?family=PT+Serif:regular,italic,bold,bolditalic"
        rel="stylesheet" type="text/css">
  <link href="//fonts.googleapis.com/css?family=PT+Sans:regular,italic,bold,bolditalic"
        rel="stylesheet" type="text/css">
  -->


  <script src="/theme/js/modernizr-2.0.js"></script>
  <script src="/theme/js/ender.js"></script>
  <script src="/theme/js/octopress.js" type="text/javascript"></script>
</head>

<body >
  <header role="banner"
  >
<hgroup>
  <h1><a href="/">cat writebug.cn/history</a></h1>
    <h2>一个开发者的技术博客。</h2>
</hgroup></header>
  <nav role="navigation"><ul class="subscription" data-subscription="rss">
  <li><a href="/feeds/all.atom.xml" rel="subscribe-rss">RSS</a></li>
</ul>


<ul class="main-navigation">
    <li><a href="/">Home</a></li>
    <li><a href="/archives.html">Archive</a></li>
    <li><a href="/pages/todolist.html">TodoList</a></li>
    <li><a href="/pages/about.html">About</a></li>
</ul></nav>
  <div id="main">
    <div id="content">
<div>
  <article class="hentry" role="article">
<header>
      <h1 class="entry-title">gdb的基本使用方法</h1>
    <p class="meta">
<time datetime="2023-07-29T00:26:32+08:00" pubdate>2023-07-29 00:26:32</time>      
    </p>
</header>

    <div class="entry-content"><h1>获取进程的coredump （内核转储）</h1>
<h2>启用内核转储</h2>
<table>
<thead>
<tr>
<th>功能</th>
<th>命令</th>
</tr>
</thead>
<tbody>
<tr>
<td>查看coredump功能是否有效</td>
<td><code>ulimit</code>和<code>ulimit -c</code></td>
</tr>
<tr>
<td>开启内核转储</td>
<td>ulimit -c unlimited</td>
</tr>
<tr>
<td>设置coredump大小上限</td>
<td>ulimit -c 大小（Byte）</td>
</tr>
<tr>
<td>gdb调试core文件</td>
<td>gdb -c core.xxxx  ./a.</td>
</tr>
<tr>
<td>检查是否是core文件</td>
<td>file xxx输出core file</td>
</tr>
</tbody>
</table>
<h2>在专用目录中生成coredump</h2>
<p>coredump保存位置的完整路径可以通过sysctl变量<code>kernel.core_pattern</code>设置。</p>
<ul>
<li>
<p>临时修改使用<code>echo /var/core/%t-%e-%p-%c.core &gt; /proc/sys/kernel/core_pattern</code></p>
</li>
<li>
<p>或者<code>/etc/sysctl.conf</code>中设置<code>kernel.core_pattern=/var/core/%t-%e-%p-%c.core</code>。然后<code>sysctl -p</code>让配置生效。</p>
</li>
</ul>
<p>kernel.core_uses_pid=1 作用是在生成的core文件名字结尾添加<code>.PID</code>。</p>
<p>kernel.core_uses_pid=0则不添加。</p>
<h3>kernel.core_pattern中可以设置的格式符</h3>
<table>
<thead>
<tr>
<th>格式符</th>
<th>说明</th>
</tr>
</thead>
<tbody>
<tr>
<td>%%</td>
<td>%字符本身</td>
</tr>
<tr>
<td>%p</td>
<td>进程PID</td>
</tr>
<tr>
<td>%u</td>
<td>进程的真实用户ID</td>
</tr>
<tr>
<td>%g</td>
<td>进程的真实组ID</td>
</tr>
<tr>
<td>%s</td>
<td>引发coredump的信号</td>
</tr>
<tr>
<td>%t</td>
<td>转储时间戳</td>
</tr>
<tr>
<td>%h</td>
<td>主机名</td>
</tr>
<tr>
<td>%e</td>
<td>可执行文件名</td>
</tr>
<tr>
<td>%c</td>
<td>转储文件大小上限</td>
</tr>
</tbody>
</table>
<h2>使用用户程序辅助自动压缩coredump文件</h2>
<p><code>kernel.core_pattern</code>中可以加入管道符，管道符后面写程序名。</p>
<p>例如：</p>
<ul>
<li>
<p><code>echo "|/usr/local/sbin/core_helper %t %e %p %c" &gt; /proc/sys/kernel/core_pattern</code> </p>
</li>
<li>
<p>或者 sudo sysctl -w 'kernel.core_pattern=%t-%e-%p-%c.core'</p>
</li>
<li>
<p>或者 /etc/sysctl.conf<code>中设置</code>kernel.core_pattern=|/usr/local/sbin/core_helper %t %e %p %c<code>。然后sysctl -p</code>让配置生效。</p>
</li>
</ul>
<p>core_heaper 文件内容很简单：</p>
<p>cat core_heaper</p>
<div class="highlight-custom"><pre><span></span><code><span class="ch">#!/bin/sh</span>

<span class="nb">exec</span><span class="w"> </span>gzip<span class="w"> </span>-<span class="w"> </span>&gt;<span class="w"> </span>/var/core/<span class="nv">$1</span>-<span class="nv">$2</span>-<span class="nv">$3</span>-<span class="nv">$4</span>.core
</code></pre></div>

<h2>启用整个系统的coredump功能</h2>
<ul>
<li>
<p>在 service 文件 <code>[Service]</code>中添加LimitCORE=infinity， 不制service服务core文件的大小</p>
</li>
<li>
<p>使SUID 程序也转储<code>sysctl -w 'fs.suid_dumpable=1</code></p>
</li>
</ul>
<h2>systemd用户的coredumpctl</h2>
<ol>
<li>
<p>安装systemd-coredump &amp;&amp; reboot</p>
</li>
<li>
<p>sudo coredumpctl list 列出当前corefile 文件</p>
</li>
<li>
<p>sudo coredumpctl list 'smplayer' | tail -n 5</p>
</li>
<li>
<p>/var/lib/systemd/coredump/ 这是corefile 默认保存位置</p>
</li>
<li>
<p>coredumpctl -o core dump PID # 获得转储信息，输出到文件core 中</p>
</li>
<li>
<p>man systemd-coredump; man core 查看手册</p>
</li>
</ol>
<h2>利用内核转储掩码排除共享内存</h2>
<p>有些程序会使用多个进程和几个G的共享内存，coredmp时间过长。</p>
<p>在使用各个共享内存的进程中，共享内存的内容是相同的，没必要所有进程都转储共享内存。这种应用程序应当设置成只在某个进程中转储共享内存，其他进程无须转储。</p>
<p>设置方法：echo 1 &gt; <code>/proc/&lt;PID&gt;/coredump_filter</code> （16进制）</p>
<p>比特掩码对应的内存类型：</p>
<ul>
<li>(bit 0) anonymous private memory（匿名私有内存段）</li>
<li>(bit 1) anonymous shared memory（匿名共享内存段）</li>
<li>(bit 2) file-backed private memory（file-backed 私有内存段）</li>
<li>(bit 3) file-backed shared memory（file-bakced 共享内存段）</li>
<li>(bit 4) ELF header pages in file-backed private memory areas (ELF 文件映射, it is effective only if the bit 2 is cleared)</li>
<li>(bit 5) hugetlb private memory（大页面私有内存）</li>
<li>(bit 6) hugetlb shared memory（大页面共享内存）</li>
</ul>
<p>默认的coredump_filter 的值一般是0x33</p>
<p>要跳过所有的共享内存，可以设置为 <code>echo 1 &gt; /proc//coredump_filter</code></p>
<h1>调试器的基本使用方法</h1>
<h3>调试前的准备：修改编译参数</h3>
<ul>
<li>通过gcc的-g选项生成调试信息。</li>
</ul>
<p><code>gcc -Wall -O2 -g source.c</code></p>
<ul>
<li>
<p>-ggdb 选项允许使用只有GDB才能使用的额外调试信息，包括gdb扩展</p>
</li>
<li>
<p>-glevel | -ggdblevel `level取值范围 0 1 2 3。-g0不生成调试信息，否定-g。-g1生成调试信息最少，没有局部变量。-g2生成默认级别的调试信息。-g3包括额外的调试信息，支持宏定义。</p>
</li>
<li>
<p>如果使用Makefile构建，一般要求给CFLAGS中指定-g选项。</p>
</li>
</ul>
<p><code>CFLAGS = -Wall -O2 -g</code></p>
<ul>
<li>如果用configure脚本生成Makefile，可以这样用。</li>
</ul>
<p><code>./configure CFLAGS="-Wall -O2 -g"</code></p>
<p>构建方法通常会写在INTALL, README等文件中。</p>
<blockquote>
<p>-Wall -Werror 选项可以在警告发生时，当成错误来处理</p>
<p>-Wl,-Map=output.map #-Wl,的意思是把后面的参数传递给连接器，传递给连接器的参数列表需要紧跟-Wl,用逗号分隔，不能有带空格。-Wl,-Map=output.map的作用是生成map文件。map文件包含函数地址入口等信息，如果gcc编译时候没有带调试信息，可以用map来定位调用栈中的函数，也可以通过函数地址入口信息通过gdb或者代码调用函数。</p>
</blockquote>
<h2>如何知道程序带调试信息</h2>
<p><code>readelf -S ./a.out | grep \.debug</code> 如果带.debug段说明有调试信息。</p>
<h2>启动调试</h2>
<ul>
<li>
<p>gdb 可执行文件名</p>
</li>
<li>
<p>gdb --args ./a.out 可执行文件参数列表</p>
</li>
<li>
<p>gdb -p PID</p>
</li>
<li>
<p>gdb -c corefile 可执行文件</p>
</li>
</ul>
<h2>设置断点</h2>
<p>程序运行后，到达断点会自动暂停运行。</p>
<p>断点命令break,简写b。</p>
<table>
<thead>
<tr>
<th>break命令格式</th>
<th>例子</th>
</tr>
</thead>
<tbody>
<tr>
<td>break （在下一行代码上设置断点）</td>
<td>break</td>
</tr>
<tr>
<td>break 函数名</td>
<td>break sendto</td>
</tr>
<tr>
<td>break 行号</td>
<td>break 516</td>
</tr>
<tr>
<td>break 文件名:行号</td>
<td>break main.c:120</td>
</tr>
<tr>
<td>break +相对暂停位置的偏移量（行数）</td>
<td>break +3</td>
</tr>
<tr>
<td>break -相对暂停位置的偏移量（行数）</td>
<td>break -5</td>
</tr>
<tr>
<td>break *地址</td>
<td>break *0x08116fd3</td>
</tr>
</tbody>
</table>
<p>设置好的断点可以通过 <code>info break [n]</code>查看。</p>
<p>使用<code>delete [breakpoints] [n]</code> 命令删除段店，breakpoints可有可无，n为断点编号，如果省略n则删除所有断点。</p>
<h2>运行</h2>
<table>
<thead>
<tr>
<th>命令</th>
<th>说明</th>
</tr>
</thead>
<tbody>
<tr>
<td>run</td>
<td>开始运行</td>
</tr>
<tr>
<td>start</td>
<td>开始运行，并在main上暂停，相当于自动给main设置断点然后开始运行</td>
</tr>
<tr>
<td>set args [Arguments]</td>
<td>设置进程启动参数</td>
</tr>
<tr>
<td>show args</td>
<td>查看进程参数列表</td>
</tr>
</tbody>
</table>
<h2>显示代码</h2>
<p><code>list</code> 命令向下查看10行代码</p>
<p><code>list -</code> 向上查看10行代码</p>
<p><code>list LINENUM</code> 查看行号的代码</p>
<p><code>list FUNCTION</code> 查看指定函数代码</p>
<p><code>list FILE:LINENUM</code></p>
<p><code>list FILE:FUNCTION</code></p>
<p><code>list *ADDRESS</code> 按地址查看代码</p>
<h2>显示调用栈</h2>
<table>
<thead>
<tr>
<th>命令</th>
<th>说明</th>
</tr>
</thead>
<tbody>
<tr>
<td>backtrace</td>
<td>显示调用栈栈帧</td>
</tr>
<tr>
<td>bt</td>
<td>breaktrace的简写（别名）</td>
</tr>
<tr>
<td>backtrace N</td>
<td>只显示开头N个栈帧</td>
</tr>
<tr>
<td>bt N</td>
<td>只显示开头N个栈帧</td>
</tr>
<tr>
<td>backtrack -N</td>
<td>只显示最后N个栈帧</td>
</tr>
<tr>
<td>bt -N</td>
<td>只显示最后N个栈帧</td>
</tr>
<tr>
<td>backtrace full</td>
<td>不仅显示backtrace,还显示局部变量</td>
</tr>
<tr>
<td>bt full</td>
<td>不仅显示backtrace,还显示局部变量</td>
</tr>
<tr>
<td>backtrace full N</td>
<td>不仅显示backtrace,还显示局部变量，N的含义同上</td>
</tr>
<tr>
<td>bt full N</td>
<td>不仅显示backtrace,还显示局部变量，N的含义同上</td>
</tr>
<tr>
<td>backtrace full N</td>
<td>不仅显示backtrace,还显示局部变量，N的含义同上</td>
</tr>
<tr>
<td>bt full -N</td>
<td>不仅显示backtrace,还显示局部变量，N的含义同上</td>
</tr>
<tr>
<td>info stack</td>
<td>backtrace的别名</td>
</tr>
<tr>
<td>where</td>
<td>backtrace的别名</td>
</tr>
</tbody>
</table>
<h2>显示局部变量和切换调用栈</h2>
<p><code>info locals</code> 显示局部变量</p>
<p><code>info args</code> 查看函数参数</p>
<p><code>info frame</code>查看调用栈帧相关信息</p>
<p><code>up [N]</code>  查看上一层函数调用栈，N为层数，默认是1</p>
<p><code>down [N]</code> 查看下一层函数调用栈，N为层数，默认是1</p>
<p><code>frame &lt;栈帧N&gt;</code>  N为bt命令显示的编号，查看第N个调用栈</p>
<p><code>frame</code> 切换到当前线程正在执行的调用栈</p>
<h2>显示变量</h2>
<p>print命令可以显示变量，简写p。</p>
<p>格式： print 变量。</p>
<table>
<thead>
<tr>
<th>例子</th>
<th>显示</th>
</tr>
</thead>
<tbody>
<tr>
<td>p argv</td>
<td>(char**)0xbf9cd714</td>
</tr>
<tr>
<td>p *argv</td>
<td>"./a.out"</td>
</tr>
<tr>
<td>p argv[0]</td>
<td>"./a.out"</td>
</tr>
<tr>
<td>p argv[1]</td>
<td>"hello"</td>
</tr>
</tbody>
</table>
<h2>自动显示变量的值</h2>
<p><code>display</code> 命令用于监视变量或者内存的值，每次 gdb 中断，都会自动输出这些被监视变量或内存的值。</p>
<ul>
<li>
<p>display命令的使用格式是 <code>display 变量名/内存地址/寄存器名</code>。</p>
</li>
<li>
<p><code>info display</code> # 查看display设置的自动显示的信息。</p>
</li>
<li>
<p>undisplay &lt;编号&gt; # 取消自动显示变量（info display时显示的编号）</p>
</li>
<li>
<p>delete display range… # range为编号，或者空格分割的编号，或者 编号-编号，用来删除一个范围</p>
</li>
</ul>
<h2>查看寄存器</h2>
<p>info registers可以查看寄存器，简写为info reg。</p>
<p>在寄存器名称前加上$, 可以用p命令查看寄存器。</p>
<p><code>p $rax</code></p>
<p>程序指针可以写为 <code>$pc</code>, 也可以写为 <code>$eip</code>。</p>
<p><code>p   $pc</code> 能够常看当前执行的程序地址。</p>
<p>print 命令支持选择显示的格式。<code>print/c $rax</code> <code>p/u $rdx</code></p>
<h4>print命令可以使用的显示格式</h4>
<table>
<thead>
<tr>
<th>格式</th>
<th>说明</th>
</tr>
</thead>
<tbody>
<tr>
<td>x</td>
<td>显示为16进制数字</td>
</tr>
<tr>
<td>d</td>
<td>显示为十进制数字</td>
</tr>
<tr>
<td>u</td>
<td>显示为无符号十进制数</td>
</tr>
<tr>
<td>o</td>
<td>显示为8进制数字</td>
</tr>
<tr>
<td>t</td>
<td>显示为2进制数字，t的由来是two</td>
</tr>
<tr>
<td>a</td>
<td>显示地址</td>
</tr>
<tr>
<td>c</td>
<td>显示为字符（ASCII）</td>
</tr>
<tr>
<td>f</td>
<td>显示为浮点小数</td>
</tr>
<tr>
<td>s</td>
<td>显示为字符串</td>
</tr>
<tr>
<td>i</td>
<td>显示为汇编语言。</td>
</tr>
</tbody>
</table>
<h2>查看内存</h2>
<p>x命令可以显示内存中的内容。x这个名字的由来是eXamining.</p>
<p>格式： <code>x/格式 地址</code>  <code>x /格式 寄存器</code></p>
<p>一般使用x命令时，格式为 <code>x/NFU ADDR</code>。addr为希望显示的地址。N为重复次数，F为上一节中的显示格式（x,d,u,o,t,a,c,f,s,i）。U下是面的单位。</p>
<table>
<thead>
<tr>
<th>U代表的单位</th>
<th>说明</th>
</tr>
</thead>
<tbody>
<tr>
<td>b</td>
<td>字节</td>
</tr>
<tr>
<td>h</td>
<td>半字（2字节）</td>
</tr>
<tr>
<td>w</td>
<td>字（4字节，默认值）</td>
</tr>
<tr>
<td>g</td>
<td>双字（8字节）</td>
</tr>
</tbody>
</table>
<p>显示<code>$pc</code>所指地址开头的10条指令： <code>x /10i $pc</code></p>
<h3>反汇编指令 disassemble</h3>
<p>反汇编指令 disassemble,简写为disas。</p>
<table>
<thead>
<tr>
<th>格式</th>
<th>说明</th>
<th>例子</th>
</tr>
</thead>
<tbody>
<tr>
<td>disas</td>
<td>反汇编当前整个函数</td>
<td>disas</td>
</tr>
<tr>
<td>disas 程序计数器</td>
<td>反汇编程序计数器所在的函数整个函数</td>
<td>disas $pc</td>
</tr>
<tr>
<td>disas 开始地址 结束地址</td>
<td>反汇编从开始地址到结束地址之间的部分</td>
<td><code>disas $pc $pc+50</code></td>
</tr>
</tbody>
</table>
<h2>单步执行</h2>
<p>单步执行的意思是根据代码一行一行的执行。</p>
<p>单步执行命令为next,简写n.</p>
<p>进入函数内部的单步命令为step,简写为p.</p>
<table>
<thead>
<tr>
<th>命令</th>
<th>简写</th>
<th>含义</th>
</tr>
</thead>
<tbody>
<tr>
<td>next</td>
<td>n</td>
<td>执行下一行。执行完毕后显示再下一行的源码。不会进入下一行中的函数内部。</td>
</tr>
<tr>
<td>step</td>
<td>s</td>
<td>执行下一行，但会进入下一行中函数内部。</td>
</tr>
<tr>
<td>nexti</td>
<td>-</td>
<td>逐条执行汇编指令 ，不会进入函数内部。</td>
</tr>
<tr>
<td>stepi</td>
<td>-</td>
<td>逐条执行汇编指令 ，会进入函数内部。</td>
</tr>
</tbody>
</table>
<h2>继续运行</h2>
<p>continue命令（简写c）可以继续运行程序。程序会在遇到断点后再次暂停运行。如果没有断点，就会一直运行到结束。</p>
<table>
<thead>
<tr>
<th>命令</th>
<th>说明</th>
</tr>
</thead>
<tbody>
<tr>
<td>continue</td>
<td>继续运行</td>
</tr>
<tr>
<td>continue 次数</td>
<td>指定次数忽略遇到的断点。例如continue 5，遇到5次断点不暂停运行。</td>
</tr>
</tbody>
</table>
<h2>监视点</h2>
<p>watch命令可以找到<strong>变量或内存</strong>在何时被改变或访问。</p>
<table>
<thead>
<tr>
<th>命令</th>
<th>说明</th>
</tr>
</thead>
<tbody>
<tr>
<td>awatch &lt;表达式&gt;</td>
<td>表达式被访问，改变时暂停运行。即watch和rwatch。</td>
</tr>
<tr>
<td><strong>watch &lt;表达式&gt;</strong></td>
<td><strong>表达式发生变化是暂停运行。</strong></td>
</tr>
<tr>
<td>rwatch &lt;表达式&gt;</td>
<td>表达式被访问是暂停运行。</td>
</tr>
</tbody>
</table>
<p>表达式的的意思是常量或者变量。例如<code>watch name</code>  <code>watch argv[0]</code></p>
<h2>删除断点和监视点</h2>
<table>
<thead>
<tr>
<th>命令</th>
<th>说明</th>
</tr>
</thead>
<tbody>
<tr>
<td>info b</td>
<td>显示断点和监视点</td>
</tr>
<tr>
<td>delete &lt;编号&gt;</td>
<td>删除指定的断点或监视点</td>
</tr>
<tr>
<td>delete</td>
<td>删除所有断点和监视点</td>
</tr>
</tbody>
</table>
<h2>其他断点</h2>
<ul>
<li>
<p>硬件断点<code>hbreak</code>，适用于ROM空间等无法修改的内存区域中的程序，在有些架构中无法使用。</p>
</li>
<li>
<p>临时断点 <code>tbreak</code>和临时硬件断点<code>thbreak</code>，与断点（硬件断点）基本相同，不同之处是临时断点会在到达断点程序暂停时被删除，所以只需要暂停一次时候使用起来很方便。</p>
</li>
<li>
<p>遗憾的是没有临时监视点。</p>
</li>
</ul>
<h2>改变变量的值</h2>
<p><code>set variable &lt;变量&gt;=&lt;表达式&gt;</code></p>
<p><code>set variable num=0</code> 将num的值设置为0</p>
<h2>生成coredump文件</h2>
<p>gdb中 <code>generate-core-file</code>命令在当前目录下生成coredump文件，可以写为<code>gcore</code>。</p>
<p>linux shell中 <code>gcore [-a] pid1 [pid2...pidN]</code> 命令可以根据进程PID生成coredump文件。</p>
<p>例如<code>gcore $(pidof emacs)</code></p>
<h2>attach到进程</h2>
<p>attachh <PID>可以attach到指定进程，和gdb -p <PID>效果类似。</p>
<p>detach 命令可以脱离调试的进程。</p>
<p>attach后，进程暂停运行，此时可以通过bt命令查看backtrace, 通过continue命令继续运行程序。</p>
<p>进程信息可以用<code>info proc</code>命令查看。</p>
<h2>条件断点</h2>
<p>有一种断点仅在特定条件下中断。</p>
<p>格式：<code>break 断点 if 条件</code></p>
<p>这条命令将测试给定的条件，如果为真则暂停运行。</p>
<p>例<code>break iseq_compile if node==0</code></p>
<p><code>condition 断点编号</code> #这条命令可以删除指定断点的出发条件。</p>
<p><code>condition 断点编号 条件</code> # 这条命令给指定的断点增加出发条件。</p>
<h2>反复执行</h2>
<table>
<thead>
<tr>
<th>命令</th>
<th>说明</th>
</tr>
</thead>
<tbody>
<tr>
<td>ignore &lt;断点编号&gt; &lt;次数&gt;</td>
<td>在指定的断点，监视点，或捕获点忽略指定的次数</td>
</tr>
<tr>
<td>continue &lt;次数&gt;</td>
<td>忽略指定次数，到达断点，监视点，捕获点不暂停运行</td>
</tr>
<tr>
<td>step 次数</td>
<td>单步运行次数（进入函数）</td>
</tr>
<tr>
<td>stepi 次数</td>
<td>单步运行汇编代码，进入函数</td>
</tr>
<tr>
<td>next 次数</td>
<td>单步运行次数（不进入函数）</td>
</tr>
<tr>
<td>nexti 次数</td>
<td>单步运行汇编代码，不进入函数</td>
</tr>
<tr>
<td>finish</td>
<td>执行完当前的函数后暂停</td>
</tr>
<tr>
<td>until</td>
<td>执行完当前的代码块，或者执行完循环后暂停，常用于跳出循环</td>
</tr>
<tr>
<td>return 表达式</td>
<td>结束当前函数调用并返回指定的值，回到上一层函数调用</td>
</tr>
<tr>
<td>jump LINE</td>
<td>跳转到指定的行执行</td>
</tr>
<tr>
<td>jump *ADDR</td>
<td>跳转到指定的地址执行</td>
</tr>
</tbody>
</table>
<h2>删除断点和禁用断点</h2>
<table>
<thead>
<tr>
<th>命令</th>
<th>说明</th>
</tr>
</thead>
<tbody>
<tr>
<td>clear 函数名</td>
<td>删除函数中的断点</td>
</tr>
<tr>
<td>clear 行号</td>
<td>删除源码行号上的断点</td>
</tr>
<tr>
<td>clear 文件名:函数名</td>
<td>删除指定文件函数中的断点</td>
</tr>
<tr>
<td>clear 文件名:行号</td>
<td>删除源码行号上的断点</td>
</tr>
<tr>
<td>clear *程序地址</td>
<td>删除位于地址的断点</td>
</tr>
<tr>
<td>delete [breakpoints] 断点编号</td>
<td>删除指定编号的断点， breakpoints关键字可以省略</td>
</tr>
<tr>
<td>delete [breakpoints]</td>
<td>删除所有断点</td>
</tr>
<tr>
<td>disable [breakpoints]</td>
<td>临时禁用所有断点，后面还能再启用</td>
</tr>
<tr>
<td>disable [breakpoints] 断点编号</td>
<td>临时禁用指定的断点，后面还能再启用</td>
</tr>
<tr>
<td>disable diaplay 显示编号</td>
<td>禁用display命令定义的自动显示</td>
</tr>
<tr>
<td>disable mem 内存区域</td>
<td>禁用mem命令定义的内存区域</td>
</tr>
<tr>
<td>enable [breakpoints]</td>
<td>启用被禁用的所有断点。</td>
</tr>
<tr>
<td>enable [breakpoints] 断点编号</td>
<td>启用指定断点</td>
</tr>
<tr>
<td>enable [breakpoints] once 断点编号</td>
<td>启用一次断点，随后禁用断点。</td>
</tr>
<tr>
<td>enable [breakpoints] delete 断点编号</td>
<td>启用一次断点，随后删除断点。</td>
</tr>
<tr>
<td>enable diaplay 显示编号</td>
<td>启用display命令定义的自动显示</td>
</tr>
<tr>
<td>enable mem 内存区域</td>
<td>启用mem命令定义的内存区域</td>
</tr>
</tbody>
</table>
<h2>显示变量类型和定义变量的文件</h2>
<p><code>whatis 表达式</code> # 显示变量类型声明</p>
<p><code>ptype 表达式</code> # 显示变量类型定义</p>
<h1>调试多线程</h1>
<p><code>info threads</code> 查看所有线程列表</p>
<p><code>thread N</code> 切换到指定线程</p>
<h1>参考资料&amp;其他学习资料</h1>
<ul>
<li>
<p>《DEBUG HACKS中文版》</p>
</li>
<li>
<p>https://visualgdb.com/gdbreference</p>
</li>
<li>
<p>man gdb</p>
</li>
<li>
<p><a href="https://sourceware.org/gdb/onlinedocs/gdb/">Debugging with GDB</a></p>
</li>
<li>
<p><a href="https://www.kancloud.cn/wizardforcel/gdb-tips-100/146724">100个gdb小技巧 </a></p>
</li>
<li>
<p><a href="http://m.biancheng.net/gdb/">GDB调试教程：1小时玩转Linux gdb命令</a></p>
</li>
</ul></div>
    <footer>
<p class="meta">
  <span class="byline author vcard">
    Posted by <span class="fn">
        zhiliao
    </span>
  </span>
<time datetime="2023-07-29T00:26:32+08:00" pubdate>2023-07-29 00:26:32</time>  <span class="categories">
    <a class='category' href='/category/programming.html'>programming</a>
  </span>
  <span class="categories">
    <a class="category" href="/tag/debug.html">debug</a>,    <a class="category" href="/tag/programming.html">programming</a>,    <a class="category" href="/tag/linux.html">linux</a>,    <a class="category" href="/tag/c.html">C</a>  </span>
</p><div class="sharing">
</div>    </footer>
  </article>

</div>

<aside class="sidebar">
<section>
  <h1>Recent Posts</h1>
  <ul id="recent_posts">
    <li class="post">
        <a href="/posts/2023/08/22/bash-conversion.html">bash进制转换</a>
    </li>
    <li class="post">
        <a href="/posts/2023/08/16/remap-caps-ctrl.html">在Linux下交换Ctrl与大写锁定键</a>
    </li>
    <li class="post">
        <a href="/posts/2023/08/15/learn-java.html">java入门精粹</a>
    </li>
    <li class="post">
        <a href="/posts/2023/08/04/tcl-expect.html">Tcl 和 expect教程</a>
    </li>
    <li class="post">
        <a href="/posts/2023/08/01/armbian-config-software.html">armbian-config 支持自动安装的软件</a>
    </li>
  </ul>
</section><section>
  <h1>Categories</h1>
    <ul id="recent_posts">
      <li><a href="/category/android.html">android (2)</a></li>
      <li><a href="/category/blog.html">blog (1)</a></li>
      <li><a href="/category/bootloader.html">bootloader (2)</a></li>
      <li><a href="/category/container.html">container (1)</a></li>
      <li><a href="/category/database.html">database (1)</a></li>
      <li><a href="/category/editor.html">editor (4)</a></li>
      <li><a href="/category/filesystem.html">filesystem (1)</a></li>
      <li><a href="/category/firefox.html">firefox (1)</a></li>
      <li><a href="/category/git.html">git (4)</a></li>
      <li><a href="/category/golang.html">golang (1)</a></li>
      <li><a href="/category/gu-piao.html">股票 (1)</a></li>
      <li><a href="/category/ide.html">IDE (1)</a></li>
      <li><a href="/category/interview.html">interview (1)</a></li>
      <li><a href="/category/linux.html">linux (51)</a></li>
      <li><a href="/category/network.html">network (7)</a></li>
      <li><a href="/category/nltk.html">nltk (2)</a></li>
      <li><a href="/category/notes.html">notes (1)</a></li>
      <li><a href="/category/other.html">other (1)</a></li>
      <li><a href="/category/programming.html">programming (10)</a></li>
      <li><a href="/category/python.html">python (1)</a></li>
      <li><a href="/category/software.html">software (1)</a></li>
      <li><a href="/category/stock.html">stock (1)</a></li>
      <li><a href="/category/storage.html">storage (2)</a></li>
      <li><a href="/category/vm.html">vm (1)</a></li>
      <li><a href="/category/web.html">web (4)</a></li>
      <li><a href="/category/windows.html">windows (1)</a></li>
      <li><a href="/category/xwindow.html">xwindow (1)</a></li>
  </ul>
</section>
<section>
  <h1>Tags</h1>
    <a href="/tag/linux.html">linux</a>,    <a href="/tag/bash.html">bash</a>,    <a href="/tag/xwindow.html">Xwindow</a>,    <a href="/tag/programming-language.html">programming-language</a>,    <a href="/tag/java.html">java</a>,    <a href="/tag/programming.html">programming</a>,    <a href="/tag/software.html">software</a>,    <a href="/tag/storage.html">storage</a>,    <a href="/tag/debug.html">debug</a>,    <a href="/tag/c.html">C</a>,    <a href="/tag/git.html">git</a>,    <a href="/tag/patch.html">patch</a>,    <a href="/tag/text.html">text</a>,    <a href="/tag/selenium.html">selenium</a>,    <a href="/tag/web.html">web</a>,    <a href="/tag/docker.html">docker</a>,    <a href="/tag/flatpak.html">flatpak</a>,    <a href="/tag/interview.html">interview</a>,    <a href="/tag/qt.html">Qt</a>,    <a href="/tag/opensuse.html">openSUSE</a>,    <a href="/tag/filesystem.html">filesystem</a>,    <a href="/tag/ide.html">IDE</a>,    <a href="/tag/glang.html">glang</a>,    <a href="/tag/xdg.html">xdg</a>,    <a href="/tag/network.html">network</a>,    <a href="/tag/raspberry.html">raspberry</a>,    <a href="/tag/vm.html">vm</a>,    <a href="/tag/windows.html">windows</a>,    <a href="/tag/gdb.html">gdb</a>,    <a href="/tag/debian.html">debian</a>,    <a href="/tag/archlinux.html">archlinux</a>,    <a href="/tag/phicomm.html">phicomm</a>,    <a href="/tag/kernel.html">kernel</a>,    <a href="/tag/ext4.html">ext4</a>,    <a href="/tag/server.html">server</a>,    <a href="/tag/stock.html">stock</a>,    <a href="/tag/shu.html">书</a>,    <a href="/tag/gu-piao.html">股票</a>,    <a href="/tag/python.html">python</a>,    <a href="/tag/nltk.html">nltk</a>,    <a href="/tag/command.html">command</a>,    <a href="/tag/shell.html">shell</a>,    <a href="/tag/terminal.html">terminal</a>,    <a href="/tag/other.html">other</a>,    <a href="/tag/wireless.html">wireless</a>,    <a href="/tag/android.html">android</a>,    <a href="/tag/gtk.html">gtk+</a>,    <a href="/tag/gnome.html">gnome</a>,    <a href="/tag/keyboard.html">keyboard</a>,    <a href="/tag/firefox.html">firefox</a>,    <a href="/tag/arch.html">arch</a>,    <a href="/tag/database.html">database</a>,    <a href="/tag/mysql.html">mysql</a>,    <a href="/tag/notes.html">notes</a>,    <a href="/tag/sysctl.html">sysctl</a>,    <a href="/tag/vim.html">vim</a>,    <a href="/tag/editor.html">editor</a>,    <a href="/tag/pelican.html">pelican</a>,    <a href="/tag/blog.html">blog</a>,    <a href="/tag/book.html">book</a>,    <a href="/tag/bootloader.html">bootloader</a></section>
    <section>
        <h1>Social</h1>
        <ul>
            <li><a href="https://github.com/zhangjiaxing" target="_blank">github</a></li>
            <li><a href="http://wpa.qq.com/msgrd?v=3&uin=347820393&site=qq&menu=yes" target="_blank">qq</a></li>
            <li><a href="http://www.writebug.cn" target="_blank">blog</a></li>
            <li><a href="http://gallery.writebug.cn" target="_blank">gallery</a></li>
        </ul>
    </section>
    <section>
        <h1>Blogroll</h1>
        <ul>
            <li><a href="http://getpelican.com/" target="_blank">Pelican</a></li>
        </ul>
    </section>

</aside>
    </div>
  </div>
  <footer role="contentinfo">
<p>
    Copyright &copy;  2013&ndash;2023  zhiliao &mdash;
  <span class="credit">Powered by <a href="http://getpelican.com">Pelican</a></span>
</p>  </footer>
</body>
</html>